#ifndef HTTP_CONNECTION
#define HTTP_CONNECTION

#include <cstdarg>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <exception>

#include <fcntl.h>
#include <errno.h>
#include <signal.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/uio.h>
#include <sys/epoll.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>

#include "Locker.hpp"

using std::cout, std::cerr, std::endl;
using std::exception;
using std::ostringstream;

constexpr char ok_200_title[] = "OK";
constexpr char error_400_title[] = "Bad Request";
constexpr char error_400_form[] = "Your request has bad syntax or is inherently impossible to satisfy.\n";
constexpr char error_403_title[] = "Forbidden";
constexpr char error_403_form[] = "You do not have permission to get file from this server.\n";
constexpr char error_404_title[] = "Not Found";
constexpr char error_404_form[] = "The requested file was not found on this server.\n";
constexpr char error_500_title[] = "Internal Error";
constexpr char error_500_form[] = "There was an unusual problem serving the requested file.\n";

// 将文件描述符，设置为非阻塞
void set_fd_non_blocking(int fd) {
    int old_flag = fcntl(fd, F_GETFL);
    if (old_flag == -1) {
        cerr << "Fcntl Get Falg Fail, errno = " << errno << endl;
        perror("Fcntl Get Falg Fail, ");
        throw exception();
    }

    int new_flag = old_flag | O_NONBLOCK;
    int res = fcntl(fd, F_SETFL, new_flag);
    if (res == -1) {
        cerr << "Fcntl Set Falg Fail, errno = " << errno << endl;
        perror("Fcntl Set Falg Fail, ");
        throw exception();
    }
}

// 将文件描述符添加到epoll中
void epoll_add_file_descriptor(int epoll_fd, int add_fd, bool one_shot) {
    struct epoll_event event;
    event.data.fd = add_fd;
    event.events = EPOLLIN | EPOLLRDHUP; // 在底层处理客户端主动断开的情况。

    // one-shot防止事件被重复触发
    if (one_shot) {
        event.events |= EPOLLONESHOT;
    }

    // 添加文件描述符
    int res = epoll_ctl(epoll_fd, EPOLL_CTL_ADD, add_fd, &event);
    if (res == -1) {
        cerr << "Epoll Ctl Add Fail, errno = " << errno << endl;
        perror("Epoll Ctl Add Fail, ");
        throw exception();
    }

    // 由于使用了epoll，需要将文件描述符设置为非阻塞的
    set_fd_non_blocking(add_fd);
}

// 将文件描述符从epoll中删除
void epoll_del_file_descriptor(int epoll_fd, int del_fd) {
    int res = 0;

    res = epoll_ctl(epoll_fd, EPOLL_CTL_DEL, del_fd, nullptr);
    if (res == -1) {
        cerr << "Epoll Ctl Del Fail, errno = " << errno << endl;
        perror("Epoll Ctl Del Fail, ");
        throw exception();
    }

    res = close(del_fd);
    if (res == -1) {
        cerr << "Close File Descriptor Fail, errno = " << errno << endl;
        perror("Close File Descriptor Fail, ");
        throw exception();
    }
}

// 修改epoll中的文件描述符
void epoll_mod_file_descriptor(int epoll_fd, int mod_fd, int mod_event) {
    struct epoll_event event;
    event.data.fd = mod_fd;
    event.events = mod_event | EPOLLONESHOT | EPOLLRDHUP; // 重置one-shot，确保下一次可读事件能够被成功触发

    int res = epoll_ctl(epoll_fd, EPOLL_CTL_MOD, mod_fd, &event);
    if (res == -1) {
        cerr << "Epoll Ctl Mod Fail, errno = " << errno << endl;
        perror("Epoll Ctl Mod Fail, ");
        throw exception();
    }
}

/**
 * 2023-07-04
 * 处理HTTP请求的类
 */
class HttpConnection {
public:
    // HTTP请求方法，这里只支持GET
    enum METHOD {
        GET = 0, 
        POST, 
        HEAD, 
        PUT, 
        DELETE, 
        TRACE, 
        OPTIONS, 
        CONNECT
    };

    /**
     * 解析客户端请求时，主状态机的状态
     */
    enum CHECK_STATE { 
        CHECK_STATE_REQUESTLINE = 0, // CHECK_STATE_REQUESTLINE：当前正在分析请求行
        CHECK_STATE_HEADER,          // CHECK_STATE_HEADER：当前正在分析头部字段
        CHECK_STATE_BODY             // CHECK_STATE_BODY：当前正在解析请求体
    };

    /**
     * 从状态机的三种可能状态，即行的读取状态，分别表示
     */
    enum LINE_STATE { 
        LINE_OK = 0, // 1.读取到一个完整的行 
        LINE_BAD,    // 2.行出错 
        LINE_OPEN    // 3.行数据尚且不完整
    };

    /**
     * 服务器处理HTTP请求的可能结果，报文解析的结果
     */
    enum HTTP_CODE { 
        NO_REQUEST,         // 请求不完整，需要继续读取客户数据
        GET_REQUEST,        // 表示获得了一个完成的客户请求
        BAD_REQUEST,        // 表示客户请求语法错误
        NO_RESOURCE,        // 表示服务器没有资源
        FORBIDDEN_REQUEST,  // 表示客户对资源没有足够的访问权限
        FILE_REQUEST,       // 文件请求，获取文件成功
        INTERNAL_ERROR,     // 表示服务器内部错误
        CLOSED_CONNECTION   // 表示客户端已经关闭连接了
    };

    /**
     * 定义响应数据中，Content-Type的类型 
     */
    enum CONTENT_TYPE {
        HTML,
        JPEG,
        PNG
    };

private:
    // 客户端的socket地址
    struct sockaddr_in client_address;

    // 读缓冲区的大小，静态常量，Byte
    static constexpr int READ_BUFFER_SIZE = 5 * 1024;

    // 该http连接对应的socket
    int client_socket_fd = -1;

    // 读缓冲区
    char read_buffer[READ_BUFFER_SIZE + 1] = {};

    // 记录一下，读缓冲区被用到了哪个位置
    int read_index = 0;

    // 记录一下，正在处理的字符，在读缓冲区中的位置
    int checked_index = 0;

    // 当前正在解析的行的起始位置
    int current_line_begin_index = 0;

    // 记录当前主状态机的状态，即当前正在解析首行、头部，还是主体
    CHECK_STATE check_state = CHECK_STATE_REQUESTLINE;

    // 写缓冲区的大小，静态常量，Byte
    static constexpr int WRITE_BUFFER_SIZE = 5 * 1024;

    // 写缓冲区
    char write_buffer[WRITE_BUFFER_SIZE + 1] = {};

    // 记录一下，写缓冲区呗用到了哪个位置
    int write_index = 0;

    // 请求首行，客户端请求方法
    METHOD request_method;

    // 请求首行，客户端请求路径
    char *request_url = nullptr;

    // 请求首行，客户端请求的HTTP版本
    char *request_http_version = nullptr;

    // 请求头部，Host字段
    char *request_header_host = nullptr;

    // 请求头部，Connection字段，记录需不需要keep-alive
    bool request_header_connection = false; 

    // 请求头部，Content-Length字段，记录消息主体的长度
    int request_header_content_length = 0;

    // 客户端请求的资源的类型
    CONTENT_TYPE content_type;

    // 客户端需要请求的文件的stat
    struct stat file_stat;

    // 客户端需要请求的文件的内存映射
    char *file_address = nullptr;

    // 使用分散写，来写响应数据，会用到的结构体
    struct iovec write_iv[2];

    // 分散写的块的数量
    int write_iv_count = 0;

    // 要发送的响应数据的字节数
    int bytes_to_send = 0;

    // 已发送的响应数据的字节数
    int bytes_sended = 0;

    // 初始化，读取请求、解析请求、生成响应、写入响应，相关的变量
    void init_variable() {
        // 读取请求数据相关的变量
        this->read_index = 0;

        // 解析请求数据相关的变量
        this->check_state = CHECK_STATE_REQUESTLINE;
        this->checked_index = 0;
        this->current_line_begin_index = 0;
        this->request_method = GET;
        this->request_url = nullptr;
        this->request_http_version = nullptr;
        this->request_header_host = nullptr;
        this->request_header_connection = false;
        this->request_header_content_length = 0;
        this->file_address = nullptr;

        memset(this->read_buffer, 0, HttpConnection::READ_BUFFER_SIZE + 1);

        // 生成响应数据相关的变量
        this->write_index = 0;
        this->write_iv_count = 0;

        memset(this->write_buffer, 0, HttpConnection::WRITE_BUFFER_SIZE + 1);

        // 写入响应数据相关的变量
        this->bytes_to_send = 0;
        this->bytes_sended = 0;
    }

    // 解析出单独一行的数据，判断依据是\r\n
    LINE_STATE parse_line() {
        char tmp;

        for (; this->checked_index < this->read_index; ++this->checked_index) {
            tmp = this->read_buffer[this->checked_index];

            if (tmp == '\r') {
                // 数据不完整的情况
                if (this->checked_index + 1 >= this->read_index) {
                    return LINE_OPEN;
                }
                
                // 遇到了连续的\r\n，即遇到了完整的一行数据
                else if (this->read_buffer[this->checked_index + 1] == '\n') {
                    // 原本\r\n的位置，改为\0，用于之后读取整行的数据
                    this->read_buffer[this->checked_index] = '\0';
                    this->read_buffer[this->checked_index + 1] = '\0';
                    this->checked_index += 2;
                    return LINE_OK;
                }

                // 其他情况，数据有误
                else {
                    return LINE_BAD;
                }
            }

            else if (tmp == '\n') {
                // 前一次从socket中读取的数据，和后一次从socket中读取的数据，拼起来，有了一个\r\n
                if (this->checked_index > 1 && this->read_buffer[this->checked_index - 1] == '\r') {
                    // 原本\r\n的位置，改为\0，用于之后读取整行的数据
                    this->read_buffer[this->checked_index - 1] = '\0';
                    this->read_buffer[this->checked_index] = '\0';
                    this->checked_index += 1;
                    return LINE_OK;
                }

                // 其他情况，数据有误
                else {
                    return LINE_BAD;
                }
            }
        }

        // 如果在上面的for循环中，没有return，说明数据还不完整
        return LINE_OPEN;
    }

    // 解析请求首行，获取请求方法、目标URL、HTTP版本
    HTTP_CODE parse_request_line(char raw_text[]) {
        // 提取客户端请求中的目标URL
        this->request_url = strpbrk(raw_text, " \t");
        if (this->request_url == nullptr) {
            cerr << "Can't Find URL in Request Line" << endl;
            return BAD_REQUEST;
        } else {
            *this->request_url = '\0';
            this->request_url += 1;
        }

        // 提取客户端请求中的请求方法
        char *method = raw_text;
        if (strcasecmp(method, "GET") == 0) {
            this->request_method = GET;
        } else {
            cerr << "HTTP Method not Allowed" << endl;
            return BAD_REQUEST; // 这里不支持除了Get以外的其他方法
        }

        // 提取客户端请求中的HTTP版本
        this->request_http_version = strpbrk(this->request_url, " \t");
        if (this->request_http_version == nullptr) {
            cerr << "Can't Find HTTP Version in Request Line" << endl;
            return BAD_REQUEST;
        } else {
            *this->request_http_version = '\0';
            this->request_http_version += 1;
        }
        
        // 成功读取请求首行数据
        this->check_state = CHECK_STATE_HEADER;
        return NO_REQUEST;
    }

    // 解析请求头部（Headers）
    HTTP_CODE parse_request_header(char raw_text[]) {
        // 如果上来就直接遇到空行，说明头部解析完毕，接下来要解析主体了
        if (raw_text[0] == '\0') {
            // 如果之前解析到的Content-Lenght字段不为0，说明我们还需要读取消息主体
            if (this->request_header_content_length > 0) {
                this->check_state = CHECK_STATE_BODY;
                return NO_REQUEST;
            }

            // 如果没有消息主体，则全部请求数据解析完毕
            else {
                return GET_REQUEST;
            }
        }

        // 解析Connection字段
        if (strncasecmp(raw_text, "Connection:", 11) == 0) {
            raw_text += 11;
            raw_text += strspn(raw_text, " \t");

            if (strcasecmp(raw_text, "Keep-Alive") == 0) {
                this->request_header_connection = true;
            } else {
                this->request_header_connection = false;
            }
        }

        // 解析Content-Length字段
        if (strncasecmp(raw_text, "Content-Length:", 15) == 0) {
            raw_text += 15;
            raw_text += strspn(raw_text, " \t");
            this->request_header_content_length = atoi(raw_text);
        }

        // 解析Host字段
        if (strncasecmp(raw_text, "Host:", 5) == 0) {
            raw_text += 5;
            raw_text += strspn(raw_text, " \t");
            this->request_header_host = raw_text;
        }

        return NO_REQUEST;
    }

    // 解析请求主体（Body）
    HTTP_CODE parse_request_body(char raw_text[]) {
        // 检查一下有没有读完
        if (this->read_index >= this->checked_index + this->request_header_content_length) {
            raw_text[this->request_header_content_length] = '\0';
            return GET_REQUEST;
        } else {
            return NO_REQUEST;
        }
    }

    // 处理解析好的数据
    HTTP_CODE parse_request_resource() {
        // 拼接客户端请求的资源，在服务器上的绝对路径
        char resource_location[300];
        sprintf(resource_location, "/home/shiyuxin/CPPServer/CPPServer/Resources%s", this->request_url);

        if (strcasecmp(this->request_url, "/Home.html") == 0) {
            this->content_type = HTML;
        }

        else if (strcasecmp(this->request_url, "/Secret.html") == 0) {
            this->content_type = HTML;
        }

        else if (strcasecmp(this->request_url, "/Background.jpg") == 0) {
            this->content_type = JPEG;
        }

        else if (strcasecmp(this->request_url, "/Two.png") == 0) {
            this->content_type = PNG;
        }

        // 处理文件不存在的情况
        if (stat(resource_location, &this->file_stat) == -1) {
            return NO_RESOURCE;
        }

        // 判断访问权限
        if (!(this->file_stat.st_mode & S_IROTH)) {
            return FORBIDDEN_REQUEST;
        }

        // 以只读方式打开文件
        int fd = open(resource_location, O_RDONLY);
        if (fd == -1) {
            cerr << "Open Server File Fail, errno = " << errno << endl;
            perror("Open Server File Fail, ");
            throw exception();
        }

        // 创建内存映射
        this->file_address = (char*)mmap(nullptr, this->file_stat.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
        close(fd);

        return FILE_REQUEST;
    }

    // 解析、处理，客户端的请求数据
    HTTP_CODE process_read() {
        LINE_STATE line_status = LINE_OK;
        HTTP_CODE process_res = NO_REQUEST;
        char *line_text = nullptr;

        // 不退出while循环的条件是，正常解析到了请求体，或者解析到了一行完整的数据
        while ((this->check_state == CHECK_STATE_BODY && line_status == LINE_OK) || (line_status = this->parse_line()) == LINE_OK) {
            // 获取一行数据
            line_text = this->read_buffer + this->current_line_begin_index;
            this->current_line_begin_index = this->checked_index;

            switch (this->check_state) {
                // 解析请求首行
                case CHECK_STATE_REQUESTLINE: {
                    process_res = this->parse_request_line(line_text);

                    // 如果客户端请求数据中，出现语法错误，直接退出解析
                    if (process_res == BAD_REQUEST) {
                        return BAD_REQUEST;
                    } 
                    
                    break;
                }

                // 解析请求头部
                case CHECK_STATE_HEADER: {
                    process_res = this->parse_request_header(line_text);

                    // 如果客户端请求数据中，出现语法错误，直接退出解析
                    if (process_res == BAD_REQUEST) {
                        return BAD_REQUEST;
                    } 
                    
                    // 头部解析完成后，生成具体的解析信息
                    else if (process_res == GET_REQUEST) {
                        return this->parse_request_resource();
                    }

                    break;
                }

                // 解析请求主体
                case CHECK_STATE_BODY: {
                    process_res = this->parse_request_body(line_text);

                    // 请求主体解析完成，生成具体的解析信息
                    if (process_res == GET_REQUEST) {
                        return this->parse_request_resource();
                    }

                    line_status = LINE_OPEN;
                    break;
                }

                default: {
                    return INTERNAL_ERROR;
                }
            }
        }

        return NO_REQUEST;
    }

    // 往写缓冲中写入待发送的数据
    bool add_response( const char* format, ... ) {
        if (this->write_index >= HttpConnection::WRITE_BUFFER_SIZE) {
            return false;
        }

        va_list arg_list;
        va_start(arg_list, format);
        int len = vsnprintf(this->write_buffer + this->write_index, WRITE_BUFFER_SIZE - 1 - this->write_index, format, arg_list);

        if(len >= (WRITE_BUFFER_SIZE - 1 - this->write_index)) {
            return false;
        }

        this->write_index += len;
        va_end(arg_list);

        return true;
    }

    // 向写缓冲区中，写入响应首行
    bool add_status_line( int status, const char* title ) {
        return add_response("%s %d %s\r\n", "HTTP/1.1", status, title);
    }

    // 向写缓冲区中，写入响应头部
    bool add_headers(int content_len) {
        if (!add_content_length(content_len)) {
            return false;
        }

        if (!add_content_type()) {
            return false;
        }

        if (!add_linger()) {
            return false;
        }

        if (!add_blank_line()) {
            return false;
        }

        return true;
    }

    // 响应数据中，头部字段的Content-Length
    bool add_content_length(int content_len) {
        return add_response("Content-Length: %d\r\n", content_len);
    }

    // 响应数据中，头部字段的Connection
    bool add_linger() {
        return add_response("Connection: %s\r\n", (this->request_header_connection) ? "keep-alive" : "close");
    }

    // 响应数据中，头部与主体之间的空行
    bool add_blank_line() {
        return add_response("%s", "\r\n");
    }

    // 响应数据中，响应主体
    bool add_body(const char* content) {
        return add_response("%s", content);
    }

    bool add_content_type() {
        switch (this->content_type) {
            case HTML:
                return add_response("Content-Type:%s\r\n", "text/html");
                break;
            
            case JPEG:
                return add_response("Content-Type:%s\r\n", "image/jpeg");
                break;
            
            case PNG:
                return add_response("Content-Type:%s\r\n", "image/png");
            
            default:
                return add_response("Content-Type:%s\r\n", "text/plain");
        }
    }

    // 解析读取好的请求数据，和读取请求数据的结果，生成对应的响应数据
    bool process_write(HTTP_CODE read_res) {
        switch (read_res) {
            case INTERNAL_ERROR:
                if (!this->add_status_line(500, error_500_title)) {
                    return false;
                }

                if (!this->add_headers(strlen(error_500_form))) {
                    return false;
                }

                if (!this->add_body(error_500_form)) {
                    return false;
                }

                break;

            case BAD_REQUEST:
                if (!this->add_status_line(400, error_400_title)) {
                    return false;
                }

                if (!this->add_headers(strlen(error_400_form))) {
                    return false;
                }

                if (!this->add_body(error_400_form)) {
                    return false;
                }

                break;

            case NO_RESOURCE:
                if (!this->add_status_line(404, error_404_title)) {
                    return false;
                }

                if (!this->add_headers(strlen(error_404_form))) {
                    return false;
                }

                if (!this->add_body(error_404_form)) {
                    return false;
                }

                break;

            case FORBIDDEN_REQUEST:
                if (!this->add_status_line(403, error_403_title)) {
                    return false;
                }

                if (!this->add_headers(strlen(error_403_form))) {
                    return false;
                }

                if (!this->add_body( error_403_form ) ) {
                    return false;
                }

                break;

            case FILE_REQUEST:
                if (!this->add_status_line(200, ok_200_title)) {
                    return false;
                }

                if (!this->add_headers(this->file_stat.st_size)) {

                }

                this->write_iv[0].iov_base = this->write_buffer;
                this->write_iv[0].iov_len = this->write_index;
                this->write_iv[1].iov_base = this->file_address;
                this->write_iv[1].iov_len = this->file_stat.st_size;
                this->write_iv_count = 2;

                bytes_to_send = this->write_index + this->file_stat.st_size;
                return true;

            default:
                return false;
        }

        this->write_iv[0].iov_base = this->write_buffer;
        this->write_iv[0].iov_len = this->write_index;
        this->write_iv_count = 1;
        this->bytes_to_send = this->write_index;
        return true;
    }

public:
    // socket上的所有事件，都被注册到同一个epoll中
    static int shared_epoll_fd;

    // 正在连接的用户的数量
    static int connected_client;

    // 构造函数，
    HttpConnection() {

    }

    // 析构函数，
    ~HttpConnection() {

    }

    // 初始化函数，当有新的客户端连接进来，要复用HttpConnection对象时，重新初始化对象
    void init_connection (int client_socket_fd, const struct sockaddr_in& client_address) {
        // 初始化客户端连接的socket文件描述符，和socket地址
        this->client_socket_fd = client_socket_fd;
        this->client_address = client_address;

        // 初始化读取请求、解析请求、生成响应、写入响应，相关的变量
        this->init_variable();

        // 设置端口复用
        int reuse = 1;
        int res = setsockopt(this->client_socket_fd, SOL_SOCKET, SO_REUSEADDR, &reuse, sizeof(reuse));
        if (res == -1) {
            cerr << "Client Socket Set Reuse Failed, errno = " << errno << endl;
            perror("Client Socket Set Reuse Failed, ");
            throw exception();
        }

        // 将客户端socket文件描述符，添加到epoll中，等待主线程读客户端请求
        epoll_add_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, true);

        // 连接客户端数+1
        HttpConnection::connected_client += 1;
        cout << "Current Connected Client: " << HttpConnection::connected_client << endl;
    }

    // 断开与客户端的连接
    void close_connection() {
        // 从epoll中，删除文件描述符
        if (this->client_socket_fd != -1) {
            epoll_del_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd);
            HttpConnection::connected_client -= 1;

            cout << "Connection Closed, fd is " << this->client_socket_fd << ", Current Connected Clients: " << HttpConnection::connected_client << endl;

            this->client_socket_fd = -1;
        }
    }

    // 读取客户端请求数据，循环读取，知道无数据可读，或者客户端关闭连接
    bool read() {
        cout << "Reading All Client Request Data, client fd is " << this->client_socket_fd << endl;

        // 如果读缓冲区溢出，则主动关闭连接，不处理这个请求了
        if (this->read_index >= HttpConnection::READ_BUFFER_SIZE) {
            cerr << "Socket Read Buffer Exceeded, Closing Connection..." << endl;
            return false; 
        }
        
        // 循环读取数据
        int bytes_read = 0;
        while (true) {
            // 从socket中，读取数据
            bytes_read = recv(this->client_socket_fd, (this->read_buffer + this->read_index), HttpConnection::READ_BUFFER_SIZE - this->read_index, 0);

            // 处理读取错误
            if (bytes_read == -1) {
                // 已经无数据可读，由于设置了非阻塞，程序没有阻塞在recv上
                if (errno == EAGAIN || errno == EWOULDBLOCK) {
                    this->read_buffer[this->read_index] = '\0';

                    cout << this->read_buffer << endl;
                    return true;
                }

                // 真的出现了读取错误
                else {
                    cerr << "Reading Socket Fail, errno = " << errno << endl;
                    perror("Reading Socket Fail, ");
                    return false;
                }
            }

            // 处理没有读取到数据的情况，说明对方关闭了连接
            else if (bytes_read == 0) {
                cerr << "Client Closed When Reading" << endl;
                return false;
            }

            // 处理已经读取好的数据
            this->read_index += bytes_read;
        }
    }

    // 处理客户端的请求，并生成响应
    void process() {
        cout << "\t\t\tProcessing Client Request Data, client fd is " << this->client_socket_fd << endl;

        // 处理读取到的数据，返回枚举类型
        HTTP_CODE read_res = this->process_read();

        cout << "\t\t\tClient Request Method = " << (int)this->request_method << endl;
        cout << "\t\t\tClient Request URL = " << this->request_url << endl;
        cout << "\t\t\tClient Request HTTP Version = " << this->request_http_version << endl;
        cout << "\t\t\t" << endl;
        cout << "\t\t\tHeader Host is " << this->request_header_host << endl;
        cout << "\t\t\tHeader Connection Keep Alive? " << this->request_header_connection << endl;
        cout << "\t\t\tHeader Content Length is " << this->request_header_content_length << endl;

        // 请求数据不完整，还需要继续读取，重新将文件描述符添加到epoll中
        if (read_res == HTTP_CODE::NO_REQUEST) {
            cout << "\t\t\tClient Request Data Not Complete, Exit Processing" << endl;
            epoll_mod_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, EPOLLIN);
            return;
        }

        // 生成响应数据
        bool write_res = this->process_write(read_res);

        // 处理生成失败的情况
        if (!write_res) {
            cerr << "\t\t\tFail to Generate Response Data, Closing Connection..." << endl;
            this->close_connection();
            return;
        }

        this->write_buffer[this->write_index] = '\0';
        cout << "\t\t\t----- This is Response Data -----" << endl;
        cout << this->write_buffer << endl;
        cout << "\t\t\t----- End of Response Data  -----" << endl;

        // 响应数据生成成功，向epoll注册写事件
        epoll_mod_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, EPOLLOUT);
        cout << "\t\t\tGenerate Response Data Success, Waiting for Writing..." << endl;
    }

    // 向客户端写响应数据
    bool write() {
        cout << "Writing All Server Response Data, client fd is " << this->client_socket_fd << endl;
        
        int res = 0;

        // 还需要发送的响应数据字计数为0，说明这一次的响应发送完了，初始化各个变量，等待下一次请求
        if (this->bytes_to_send == 0) {
            epoll_mod_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, EPOLLIN); 
            this->init_variable();
            return true;
        }

        // 写响应数据
        while(true) {
            // 分散写
            res = writev(this->client_socket_fd, this->write_iv, this->write_iv_count);

            // 分散写的错误处理
            if ( res <= -1 ) {
                // 如果TCP写缓冲没有空间，则等待下一轮EPOLLOUT事件，虽然在此期间，服务器无法立即接收到同一客户的下一个请求，但可以保证连接的完整性。
                if( errno == EAGAIN ) {
                    epoll_mod_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, EPOLLOUT);
                    return true;
                } 
                
                // 出现了其他无法处理的错误
                else {
                    if (this->file_address) {
                        munmap(this->file_address, this->file_stat.st_size);
                        this->file_address = nullptr;
                    }
                    return false;
                }
            }

            // 记录已经发送了的数据，和没有发送的数据的长度
            this->bytes_sended += res;
            this->bytes_to_send -= res;

            // 调整分散写
            if (this->bytes_sended >= (int)this->write_iv[0].iov_len) {
                this->write_iv[0].iov_len = 0;
                this->write_iv[1].iov_base = this->file_address + (this->bytes_sended - this->write_index);
                this->write_iv[1].iov_len = this->bytes_to_send;
            } else {
                this->write_iv[0].iov_base = this->write_buffer + this->bytes_sended;
                this->write_iv[0].iov_len = this->write_iv[0].iov_len - res;
            }

            // 没有数据需要发送了
            if (bytes_to_send <= 0) {
                if (this->file_address) {
                    munmap(this->file_address, this->file_stat.st_size);
                    this->file_address = nullptr;
                }
                epoll_mod_file_descriptor(HttpConnection::shared_epoll_fd, this->client_socket_fd, EPOLLIN);

                if (this->request_header_connection) {
                    this->init_variable();
                    return true;
                } else {
                    return false;
                }
            }
        }
    }
};

int HttpConnection::shared_epoll_fd = -1;
int HttpConnection::connected_client = 0;

#endif
